#include "WaveManager.h"
#include "Wave.h"
#include "ConfigManager.h"
#include "EnemyManager.h"
#include "CoinManager.h"

WaveManager::WaveManager()
{
    static const std::vector<Wave> &waveList = ConfigManager::Instance().waveList;

    timerStartWave.SetOneShot(true);
    timerStartWave.SetWaitTime(waveList[0].interval);
    timerStartWave.SetOnTimeout(
            [&]() {
                isWaveStarted = true;
                timerSpawnEnemy.SetWaitTime(waveList[idxWave].spawn_event_list[0].interval);
                timerSpawnEnemy.Restart();
            }
    );

    timerSpawnEnemy.SetOneShot(true);
    timerSpawnEnemy.SetOnTimeout(
            [&]() {
                const std::vector<Wave::SpawnEvent> &spawnEventList = waveList[idxWave].spawn_event_list;
                const Wave::SpawnEvent &spawnEvent = spawnEventList[idxSpawnEvent];

                EnemyManager::Instance().SpawnEnemy(spawnEvent.enemyType, spawnEvent.point);

                idxSpawnEvent++;
                if (idxSpawnEvent >= spawnEventList.size()) {
                    isSpawnedLastEnemy = true;
                    return;
                }

                timerSpawnEnemy.SetWaitTime(spawnEventList[idxSpawnEvent].interval);
                timerSpawnEnemy.Restart();
            }
    );

}

void WaveManager::OnUpdate(double delta)
{
    static ConfigManager &instance = ConfigManager::Instance();

    if (instance.is_game_over)
        return;

    if (!isWaveStarted) {
        timerStartWave.OnUpdate(delta);
    } else {
        timerSpawnEnemy.OnUpdate(delta);
    }

    if (isSpawnedLastEnemy && EnemyManager::Instance().CheckCleared()) {
        CoinManager::Instance().IncreaseCoin(instance.waveList[idxWave].rewards);

        idxWave++;
        if (idxWave >= instance.waveList.size()) {
            instance.is_game_win = true;
            instance.is_game_over = true;
        } else {
            idxSpawnEvent = 0;
            isWaveStarted = false;
            isSpawnedLastEnemy = false;

            const Wave &wave = instance.waveList[idxWave];
            timerStartWave.SetWaitTime(wave.interval);
            timerStartWave.Restart();
        }
    }
}
